PyTorch

PyTorch

背景介绍

  PyTorch:是Facebook公司于2017年1月发布的神经网络,深度学习开发平台。但是PyTorch的历史可以追溯到2002年,当时Torch使用了一种小众语言Lua作为借口,使用人数较少,在2017年推出了Python接口的Torch,故称为PyTorch,现在也称为了当下最流行的深度学习框架之一。

pytorch

PyTorch特点

  PyTorch具有高度的简洁性:和TensorFlow1.x版本有较大差距,便于用户使用和理解。
  PyTorch具有较快的速度:PyTorch的速度表现胜过TensorFlow和Keras等框架。
  PyTorch使用方便:PyTorch写代码非常的优雅,所思即所写,不用考虑太多关于框架本身的束缚。
  PyTorch具有活跃的社区,目前由作者亲自维护,供广大用户的学习和交流。
  PyTorch具有功能强大的可视化组建Visdom,可以在训练时监控训练过程。

PyTorch应用

PyTorch创建tensor

tensor,arange方法

1
2
3
4
5
6
7
import torch

# torch.tensor(data, dtype) 将data转换为tensor,类型为dtype
a = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)

# torch.arange(start, end, steps, dtype) 产生连续的tensor,从start开始到end结束,步长为step
b = torch.arange(1, 10, 2)

1

zeros,zeros_like,ones,ones_like,eye方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch

# torch.zeros(size, dtype=None) 生成形状为shape值全为0的tensor
a = torch.zeros((2,3))

# torch.ones(size, dtype=None) 生成形状为shape值全为1的tensor
b = torch.ones((2,3))

# torch.zeros_like(obj, dtype) 生成形状与array相同,值全为0的tensor
c = torch.zeros_like(b)

# torch.ones_like(obj, dtype) 生成形状与array相同,值全为1的tensor
d = torch.ones_like(a)

# torch.eye(n, m) 生成n行m列的单位矩阵,m默认等于n
e = torch.eye(3, 4)

2

rand,randn,randperm,randint方法

1
2
3
4
5
6
7
8
9
10
11
12
13
import torch

# torch.rand(size) 生成形状为size的(0-1)均匀分布随机数
a = torch.rand((2,3))

# torch.randn(size) 生成形状为size的标准高斯分布随机数
b = torch.randn((2,3))

# torch.randperm(n) 生成0到n-1整数的随机排列
c = torch.randperm(10)

# torch.randint(low, high, size) 生成形状为size,最小值为low,最大值为high-1的随机整数
d = torch.randint(1, 10, (3, 3))

3

linspace,logspace方法

1
2
3
4
5
6
7
8
import torch

# torch.linspace(start, end, steps=100, dtype=None) 将start到stop等分成steps个点(默认为100个点),包括end点
a = torch.linspace(10, 20, 6)

# torch.logspace(start, stop, steps=100, base=10.0, dtype=None) 将start到stop等分成steps个点(默认为100个点),每一个点i的值为base的i次幂
b = torch.logspace(1, 2, 10)

4

is_tensor,numel,from_numpy,numpy方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import torch
import numpy as np

a = torch.arange(10, 20, 2)
b = np.arange(10, 20, 2)

# torch.is_tensor(obj) 判断obj是否为tensor
torch.is_tensor(a)

# torch.numel(obj) 计算obj中的元素个数
torch.numel(a)

# torch.from_numpy(ndarray) 将ndarray数组类型转换为tensor
c = torch.from_numpy(b)

# obj.numpy() 返回obj的ndarray数组类型
d = c.numpy()

5

shape,dtype方法

1
2
3
4
5
6
7
8
9
import torch

a = torch.randint(1, 9, (3, 3))

# obj.shape 查看obj的形状
a.shape

# obj.dtype 查看obj的元素类型
a.dtype

8

PyTorch切片与索引

[]索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import torch

a = torch.arange(27).reshape((3, 3, 3))

# obj[index0][index1]...等价于obj[index0, index1, ...] 索引
a[1][1][1]
a[1, 1, 1]

# obj[start, end, step] 切片索引
a[0:2, 0:2, 0:2]

# obj[...] ...可以代替连续的:
a[..., 0]
a[0, ...]
a[0, ..., 0]

6

gather方法

1
2
3
4
5
6
7
import torch

a = torch.arange(9).reshape((3, 3))

# torch.gather(tensor, dim, index) 按照dim和index对tensor进行索引
b = torch.gather(a, dim=0, index=torch.tensor([[0, 1, 2], [1, 2, 0], [2, 0, 1]])) 按照第一个维度行开始索引,[0, 1, 2]代表第一行的三个元素来自于a中的第一行,第二行,第三行,列按顺序第一列,第二列,第三列,即第一行的元素为a[0][0],a[1][1],a[2][2]
c = torch.gather(a, dim=1, index=torch.tensor([[0, 1, 2], [1, 2, 0], [2, 0, 1]])) 按照第二个维度列开始索引,[0, 1, 2]代表第一行的三个元素来自于a中的第一列,第二列,第三列,都属于第一行,即第一行的元素为a[0][0],a[0][1],a[0][2]

2

PyTorch维度变换

reshape,squeeze,unsqueeze,transpose方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch

a = torch.arange(12)

# obj.reshape(shape) 将obj的形状变为shape
b = a.reshape((3, 4))

# obj.unsqueeze(dim) 在dim上插入一个大小为1的轴
c = b.unsqueeze(1)

# obj.squeeze(dim) 将大小为1的轴dim删去,默认为所有大小为1的轴,如果大小不为1则不删去
d = c.squeeze()

# obj.transpose(dim0, dim1) 将obj的轴0和轴1调换,obj.t()将二维obj转置
e = b.transpose(0, 1)
f = b.t()

9

torch.broadcast_tensors方法

1
2
3
4
5
6
7
import torch

a = torch.arange(3)
b = torch.ones((3, 3, 3))

# torch.broadcast_tensors(a, b) 将a广播为b的大小,返回a广播后的tensor和b
c, d = torch.broadcast_tensors(a, b)

10

PyTorch合并与分割

cat,stack,chunk,split方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch

a = torch.arange(6).reshape((2, 3))
b = torch.arange(7,13).reshape((2, 3))

# torch.cat(tensors, dim) 将多个tensors按照dim进行合并
c = torch.cat([a, b], dim=1)

# tf.stack(tensors, dim) 增加一个新维度,并合并到该维度
d = torch.stack([a, b], dim=0)

# torch.chunk(tensor, chunks, dim) 对tensor按照dim轴进行拆分成chunks份
e, f = torch.chunk(d, 2, dim=0)

# torch.split(tensor, split_size_or_sections, dim) 对tensor按照dim轴进行拆分,如果希望均匀拆分则num_or_size_splits为常数,代表每部分的个数(不同于TensorFlow,代表分成多少个部分),否则输入一个列表,代表每一部分的数量
h = torch.split(d, 1, dim=2)

11

PyTorch数据统计

max,min方法

1
2
3
4
5
6
7
8
9
import torch

a = torch.randperm(9).reshape((3, 3))

# torch.max(obj, dim) 求在指定轴dim的最大值及其索引,默认为求全局最大值
b = torch.max(a, dim=0)

# torch.min(obj, dim) 求在指定轴dim的最小值及其索引,默认为求全局最小值
c = torch.min(a, dim=0)

12

dist,mean,median,mode方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch

a = torch.randint(3, 7, (3, 3), dtype=torch.float32).reshape((3, 3))
b = torch.randint(3, 7, (3, 3), dtype=torch.float32).reshape((3, 3))

# torch.dist(tensor1, tensor2, p) 计算tensor1-tensor2的p范数,要先转换成float32格式进行计算
c = torch.dist(a, b, 2)

# torch.mean(tensor, dim) 计算tensor的平均值
d = torch.mean(a, dim=0)

# torch.median(tensor, dim) 计算tensor的中位数及其索引
e = torch.median(a, dim=0)

# torch.mode(tensor, dim) 计算tensor的众数及其索引
f = torch.mode(a, dim=0)

13

sort,topk方法

1
2
3
4
5
6
7
8
9
import torch

a = torch.randperm(9).reshape((3, 3))

# torch.sort(tensor, dim=None, descending=False) 将tensor按照dim维度进行排序(默认为最后一个维度),descending=False默认递增排序,descending=True为递减排序
b = torch.sort(a)

# torch.topk(tensor, k, dim=None, largest=True, sorted=True) 求tensor最大或最小的k个值,dim默认为最后一个维度,largest=True表示最大k个值,largest=False表示最小k个值,sorted=True表示默认排序,sorted=False表示不排序
c = torch.topk(a, 2)

14

PyTorch张量限幅

clamp方法

1
2
3
4
5
6
import torch

a = torch.randperm(9, dtype=torch.float32).reshape((3, 3))

# torch.clamp(tensor, min, max) 将tensor中,小于min的值赋值为min,大于max的值赋值为max
b = torch.clamp(a, 3, 6)

16

PyTorch数学运算

常规运算方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import torch

a = torch.randint(-4, 5, (3, 3), dtype=torch.float32)
b = torch.randperm(9, dtype=torch.float32).reshape((3, 3))

# tensor1 op tensor2 将tensor1与tensor2进行常规的数学运算,如果维度大小不同,则进行广播,如果不能广播则报错
a + b
a * b

# torch.abs(tensor) 求tensor的绝对值
torch.abs(a)

# torch.sqrt(tensor) 求tensor的平方根
torch.sqrt(b)

# torch.sin(tensor) 求tensor的正弦值
torch.sin(a)

# torch.exp(tensor) 求e的tensor次幂
torch.exp(a)

# torch.log(tensor) 求tensor以自然对数为底的值
torch.log(b)

15

ceil,floor,round,frac,trunc方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import torch

a = torch.rand((3, 3)) * 10

# torch.ceil(tensor) 将tensor的小数部分上取整
b = torch.ceil(a)

# torch.floor(tensor) 将tensor的小数部分下取整
c = torch.floor(a)

# torch.round(tensor) 将tensor的小数部分四舍五入
d = torch.round(a)

# torch.frac(tensor) 保留tensor的小数部分
e = torch.frac(a)

# torch.trunc(tensor) 保留tensor的整数部分
f = torch.trunc(a)

17

sign,sigmoid,kthvalue方法

1
2
3
4
5
6
7
8
9
10
11
12
import torch

a = torch.randn((3, 3))

# torch.sign(tensor) 求tensor作用在符号函数上的值
b = torch.sign(a)

# torch.sigmoid(tensor) 求tensor作用在sigmoid函数上的值
c = torch.sigmoid(a)

# torch.kthvalue(tensor, k, dim=None) 求tensor第k小的值,dim默认为最后一个维度
d = torch.kthvalue(a, 2)

18

eq,equal方法

1
2
3
4
5
6
7
8
9
10
import torch

a = torch.randint(1, 5, (3, 3))
b = torch.randint(1, 5, (3, 3))

# torch.eq(tensor1, tensor2) 等价于tensor1 == tensor2,比较tensor1和tensor2是否相等,在如果相等则对应位置为True,否则为False
torch.eq(a, b)

# torch.equal(tensor1, tensor2) 比较tensor1和tensor2是否相等,如果相等则返回True,否则为False
torch.equal(a, b)

19

PyTorch线性代数

diag,trace,tril,triu方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import torch

a = torch.randperm(9).reshape((3, 3))

# torch.diag(tensor, diagonal=0) 如果tensor为一维张量,返回二维张量,如果tensor为二维张量,返回对角线张量,diagonal代表对角线的偏移量
b = torch.diag(a)

# torch.trace(tensor) 求tensor的迹
c = torch.trace(a)

# torch.tril(tensor, k=0) 返回tensor的下三角张量,偏移为k
d = torch.tril(a)

# torch.triu(tensor, k=0) 返回tensor的上三角张量,偏移为k
e = torch.triu(a)

20

inverse,eig,svd方法

1
2
3
4
5
6
7
8
9
10
11
12
import torch

a = torch.randperm(9, dtype=torch.float32).reshape((3, 3))

# torch.inverse(tensor) 求tensor的逆矩阵
b = torch.inverse(a)

# torch.eig(tensor, eigenvectors=False) 求tensor的特征值,eigenvectors=False默认不计算特征向量,eigenvectors=True计算特征向量
c = torch.eig(a, True)

# torch.svd(tensor) 求tensor的奇异值分解
U, S, V = torch.svd(a)

21

dot,mm,mv方法

1
2
3
4
5
6
7
8
9
10
11
12
13
import torch

a = torch.randperm(9).reshape((3, 3))
b = torch.tensor([1, 2, 3])

# torch.dot(tensor1, tensor2) 两个一维向量点乘
c = torch.dot(b, b)

# torch.mm(tensor1, tensor2) 矩阵乘法
d = torch.mm(a, a)

# torch.mv(tensor1, tensor2) 矩阵tensor1乘向量tensor2
e = torch.mv(a, b)

22

PyTorch深度学习

functional(函数)模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from torch.nn import functional as f

# f.relu(input) ReLu激活函数

# f.sigmoid(input) Sigmoid激活函数

# f.tanh(input) tanh激活函数

# f.softmax(input) softmax层

# f.mse_loss(input, target) 计算input和target的均方差

# f.binary_cross_entropy(input, target) 计算input和target二分类交叉熵

# f.cross_entropy(input, target)计算input和target的交叉熵,里面内置了softmax层,因此不需要先经过softmax

autograd(自动求导)模块

1
2
3
4
5
6
7
8
9
10
11
12
import torch

# torch.tensor(data ,requires_grad=True) 创建时使其具有可导属性

# obj.requires_grad_() 使已经创建的obj具有可导属性

# torch.autograd.grad(outputs, inputs) outputs对inputs进行自动求导,前提是保证inputs具有可导属性
torch.autograd.grad(res, w)

# obj.backward() 对obj进行从后向前自动求导,然后调用变量的grad成员变量即可得到其导数
res.backward()
w.grad

optim(优化器)模块

1
2
3
4
5
6
7
import torch

# torch.optim.SGD(lr=0.01, momentum=0.0, dampending=0, weight_decay=0.0, nesterov=False) 随机梯度下降优化器,学习率lr默认为0.01,动量momentum默认为0,动量抑制因子为0,学习率衰减decay默认为0,默认不使用nesterov动量

# torch.optim.RMSprop(lr=0.001, alpha=0.9, eps=None, weight_decay=0.0, momentum=0.0) RMSProp优化器,学习率lr默认为0.001,参数alpha默认为0.99,模糊因子epsilon默认为None,学习率衰减weight_decay默认为0,动量momentum默认为0

# torch.optim.Adam(lr=0.001, betas=(0.9, 0.999), eps=None, weight_decay=0.0) Adam优化器,学习率lr默认为0.001,参数beta_1默认为0.9, 参数beta_2默认为0.999,模糊因子epsilon默认为None,学习率衰减weight_decay默认为0

CPU与GPU模块

1
2
3
4
5
6
7
8
9
10
11
import torch

# torch.device(device) 返回设备对象
device = torch.device('cuda:0')

# obj.to(device) 返回一个device设备上的对象
a = a.to(device)

# obj.cpu() 返回一个CPU对象

# obj.cuda() 返回一个GPU对象

datasets(数据集)模块

1
2
3
4
5
import torchvision.datasets as dsets
import torchvision

# dsets.XXX(root, train=True, transform, download=False) 从root为打开本地目录下载XXX数据集,train=True默认为训练集,train=False为测试集,download=False默认为不从网上下载,download=True为从网站上下载,数据预处理的部分为transform
train = dsets.MNIST(root='mnist', train=True, transform=torchvision.transforms.ToTensor(), download=False)

data(数据)模块

1
2
3
4
5
import torch.utils.data as Data

# Data.DataLoader(datasets, batch_size, shuffle=False) 读取已经加载的数据集datasets,并且分成batch,每个batch的大小为batch_size,shuffle=False默认不打乱顺序,shuffle=True为打乱batch的顺序

# Data.random.split(data, [train_size, test_size]) 将data分成训练集和测试集,每部分大小为[train_size, test_size]

nn(神经网络)模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import torch.nn as nn

# nn.Sequential() 时序容器,可以传入多个网络,和TensorFlow不同,只能一个一个传入,并用逗号分隔

# nn.Linear(in_features, out_features) 创建线性层,输入维度为in_features,输出维度为out_features

# nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0) 创建一个卷积层,输入信号通道为in_channels,输出信号通道为out_channels,卷积核大小为kernel_size,核移动的步长为stride,padding为补0的层数

# nn.MaxPool2d(kernel_size, stride=None, padding=0) 创建一个最大值池化层(平均值池化为AvgPool2d),核大小为kernel_size,核移动的步长默认为核的大小,padding为补0的层数

# nn.BatchNorm1d(num_features, eps=1e-5, momentum=0.1, affine=True) 创建标准化层(二维为BatchNorm2d),num_features为要训练的数据量,

# nn.RNN(input_size, hidden_size, num_layers, nonlinearity='tanh') 创建RNN层,输入特征数量input_size,隐层结点数hidden_size,RNN层数num_layers,非线性激活函数nonlinearity默认为tanh

# nn.LSTM(input_size, hidden_size, num_layers, nonlinearity='tanh') 创建长短期记忆网络层,输入特征数量input_size,隐层结点数hidden_size,RNN层数num_layers,非线性激活函数nonlinearity默认为tanh

# nn.Dropout(p=0.5) 创建dropout层(二维为Dropout2d),随机丢弃结点的概率为p,默认为0.5

# nn.Module 自定义网络层的基类
class MyLayer(nn.Module):
def __init__(self, input_dim, output_dim):
super(MyLayer, self).__init__()

self.kernel = nn.Parameter(torch.randn(input_dim, output_dim))
self.bias = nn.Parameter(torch.randn(output_dim))

def forward(self, inputs):
out = inputs @ self.kernel + self.bias
return out

transforms(数据变换)模块

1
2
3
4
5
6
7
8
9
import torchvision.transforms as transforms

# transforms.Normalize(mean, std) 标准化操作(类方法)

# transforms.RandomRotation(n) 将图片旋转-n到n度

# transforms.ToTensor() 将numpy图片转换为tensor

# transforms.ToPILImage() 将tensor转换为numpy图片形式

models(模型)模块

1
2
3
4
5
6
7
import torchvision.models as models

# models.resnet18(pretrained=False) 获得resnet18网络结构,默认是没有经过训练的,pretrained=True是获得经过训练的参数,便于在少样本时进行迁移学习

# models.AlexNet(pretrained=False) 获得AlexNet网络结构,默认是没有经过训练的,pretrained=True是获得经过训练的参数,便于在少样本时进行迁移学习

# models.VGG16(pretrained=False) 获得VGG16网络结构,默认是没有经过训练的,pretrained=True是获得经过训练的参数,便于在少样本时进行迁移学习

save(保持)模块

1
2
3
4
5
import torch

# torch.save(obj, filename) 将obj保存在以.pkl结尾的filename文件中

# torch.load(filename) 读取filename文件中的数据信息

PyTorch小结

  由于PyTorch的简洁性和优雅性,使得PyTorch对于入门学习的人来说非常的友好,现在PyTorch也是最热门的深度学习框架之一,具有较大的潜力。

-------------本文结束感谢您的阅读-------------
0%